package com.jzo2o.customer.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.publics.SmsCodeApi;
import com.jzo2o.common.constants.CommonStatusConstants;
import com.jzo2o.common.constants.ErrorInfo;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.enums.SmsBussinessTypeEnum;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.model.CurrentUser;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.JwtTool;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.common.utils.UserContext;
import com.jzo2o.customer.enums.CertificationStatusEnum;
import com.jzo2o.customer.mapper.AgencyCertificationAuditMapper;
import com.jzo2o.customer.mapper.AgencyCertificationMapper;
import com.jzo2o.customer.model.domain.AgencyCertification;
import com.jzo2o.customer.model.domain.AgencyCertificationAudit;
import com.jzo2o.customer.model.domain.ServeProvider;
import com.jzo2o.customer.model.dto.AgencyCertificationUpdateDTO;
import com.jzo2o.customer.model.dto.request.*;
import com.jzo2o.customer.model.dto.response.AgencyCertificationAuditResDTO;
import com.jzo2o.customer.model.dto.response.LoginResDTO;
import com.jzo2o.customer.service.IAgencyCertificationService;
import com.jzo2o.customer.service.IServeProviderService;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 机构认证信息表 服务实现类
 *
 * @author itcast
 * @since 2023-09-06
 */
@Service
public class AgencyCertificationServiceImpl extends ServiceImpl<AgencyCertificationMapper, AgencyCertification> implements IAgencyCertificationService {

    @Resource
    private SmsCodeApi smsCodeApi;
    @Resource
    private IServeProviderService serveProviderService;
    @Resource
    private JwtTool jwtTool;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private AgencyCertificationAuditMapper agencyCertificationAuditMapper;
    @Resource
    private AgencyCertificationMapper agencyCertificationMapper;

    /**
     * 根据机构id更新
     *
     * @param agencyCertificationUpdateDTO 机构认证更新模型
     */
    @Override
    public void updateByServeProviderId(AgencyCertificationUpdateDTO agencyCertificationUpdateDTO) {
        LambdaUpdateWrapper<AgencyCertification> updateWrapper = Wrappers.<AgencyCertification>lambdaUpdate()
                .eq(AgencyCertification::getId, agencyCertificationUpdateDTO.getId())
                .set(AgencyCertification::getCertificationStatus, agencyCertificationUpdateDTO.getCertificationStatus())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getName()), AgencyCertification::getName, agencyCertificationUpdateDTO.getName())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getIdNumber()), AgencyCertification::getIdNumber, agencyCertificationUpdateDTO.getIdNumber())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getLegalPersonName()), AgencyCertification::getLegalPersonName, agencyCertificationUpdateDTO.getLegalPersonName())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getLegalPersonIdCardNo()), AgencyCertification::getLegalPersonIdCardNo, agencyCertificationUpdateDTO.getLegalPersonIdCardNo())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getBusinessLicense()), AgencyCertification::getBusinessLicense, agencyCertificationUpdateDTO.getBusinessLicense())
                .set(ObjectUtil.isNotEmpty(agencyCertificationUpdateDTO.getCertificationTime()), AgencyCertification::getCertificationTime, agencyCertificationUpdateDTO.getCertificationTime());
        super.update(updateWrapper);
    }

    /**
     * 机构注册
     *
     * @param institutionRegisterReqDTO 机构注册模型
     * @return 登录结果
     */
    @Override
    public LoginResDTO institutionRegister(InstitutionRegisterReqDTO institutionRegisterReqDTO) {
        // 数据校验
        if (StringUtils.isEmpty(institutionRegisterReqDTO.getVerifyCode())) {
            throw new BadRequestException("验证码错误，请重新获取");
        }
        //远程调用publics服务校验验证码是否正确
        boolean verifyResult = smsCodeApi.verify(institutionRegisterReqDTO.getPhone(), SmsBussinessTypeEnum.INSTITION_REGISTER, institutionRegisterReqDTO.getVerifyCode()).getIsSuccess();
        if (!verifyResult) {
            throw new BadRequestException("验证码错误，请重新获取");
        }
        // 登录校验
        // 根据手机号和用户类型获取服务人员或机构信息
        ServeProvider serveProvider = serveProviderService.findByPhoneAndType(institutionRegisterReqDTO.getPhone(), UserType.INSTITUTION);
        // 账号禁用校验
        if (serveProvider != null && CommonStatusConstants.USER_STATUS_FREEZE == serveProvider.getStatus()) {
            throw new CommonException(ErrorInfo.Code.ACCOUNT_FREEZED, serveProvider.getAccountLockReason());
        }
        //对密码进行加密
        institutionRegisterReqDTO.setPassword(passwordEncoder.encode(institutionRegisterReqDTO.getPassword()));
        // 自动注册
        if (serveProvider == null) {
            serveProvider = serveProviderService.add(institutionRegisterReqDTO.getPhone(), UserType.INSTITUTION, institutionRegisterReqDTO.getPassword());
        }

        // 生成登录token
        String token = jwtTool.createToken(serveProvider.getId(), serveProvider.getName(), serveProvider.getAvatar(), UserType.INSTITUTION);
        return new LoginResDTO(token);

    }

    /**
     * 机构密码重置
     *
     * @param institutionResetPasswordReqDTO 机构密码重置模型
     */
    @Override
    public void institutionResetPassword(InstitutionResetPasswordReqDTO institutionResetPasswordReqDTO) {
        // 数据校验
        if (StringUtils.isEmpty(institutionResetPasswordReqDTO.getVerifyCode())) {
            throw new BadRequestException("验证码错误，请重新获取");
        }
        //远程调用publics服务校验验证码是否正确
        boolean verifyResult = smsCodeApi.verify(institutionResetPasswordReqDTO.getPhone(), SmsBussinessTypeEnum.SERVE_STAFF_LOGIN, institutionResetPasswordReqDTO.getVerifyCode()).getIsSuccess();
        if (!verifyResult) {
            throw new BadRequestException("验证码错误，请重新获取");
        }
        //校验手机号是否存在数据库
        // 根据手机号和用户类型获取服务人员或机构信息
        ServeProvider serveProvider = serveProviderService.findByPhoneAndType(institutionResetPasswordReqDTO.getPhone(), UserType.INSTITUTION);
        if (serveProvider == null) {
            throw new BadRequestException("手机号不存在");
        }
        //对密码进行加密
        institutionResetPasswordReqDTO.setPassword(passwordEncoder.encode(institutionResetPasswordReqDTO.getPassword()));
        // 更新密码
        serveProviderService.updateById(serveProvider.setPassword(institutionResetPasswordReqDTO.getPassword()));
    }

    /**
     * 机构认证审核添加
     *
     * @param agencyCertificationAuditAddReqDTO 机构认证审核添加模型
     */
    @Override
    public void agencyCertificationAuditAdd(AgencyCertificationAuditAddReqDTO agencyCertificationAuditAddReqDTO) {
        //新增机构认证信息
        Long id = UserContext.getCurrentUser().getId();
        AgencyCertification agencyCertificationBuild = AgencyCertification.builder()
                .id(id)
                .name(agencyCertificationAuditAddReqDTO.getName())
                .idNumber(agencyCertificationAuditAddReqDTO.getIdNumber())
                .legalPersonName(agencyCertificationAuditAddReqDTO.getLegalPersonName())
                .legalPersonIdCardNo(agencyCertificationAuditAddReqDTO.getLegalPersonIdCardNo())
                .businessLicense(agencyCertificationAuditAddReqDTO.getBusinessLicense())
                .certificationStatus(CertificationStatusEnum.PROGRESSING.getStatus())
                .build();

        //新增机构认证审核信息
        AgencyCertificationAudit bean = BeanUtils.copyBean(agencyCertificationAuditAddReqDTO, AgencyCertificationAudit.class);
        bean.setServeProviderId(id);
        bean.setAuditStatus(0);

        //存在就更新不存在就插入
        if (ObjectUtil.isNull(agencyCertificationMapper.selectOne(new QueryWrapper<AgencyCertification>().eq("id", id)))) {
            agencyCertificationAuditMapper.insert(bean);
            baseMapper.insert(agencyCertificationBuild);
        } else {
            bean.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            agencyCertificationBuild.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());

            //更改认证状态
            LambdaQueryWrapper<AgencyCertificationAudit> wcaQueryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                    .eq(AgencyCertificationAudit::getServeProviderId, id);
            agencyCertificationAuditMapper.update(bean,wcaQueryWrapper);
            baseMapper.updateById(agencyCertificationBuild);
        }
    }

    /**
     * 获取当前服务人员认证审核拒绝原因
     *
     * @return 拒绝原因
     */
    @Override
    public Map<String, String> checkRejectReason() {
        //获取当前机构id
        Long serveProviderId = UserContext.currentUserId();
        //查询当前服务人员认证审核信息
        LambdaQueryWrapper<AgencyCertificationAudit> wcaQueryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                .eq(AgencyCertificationAudit::getAuditStatus, 1)
                .eq(AgencyCertificationAudit::getServeProviderId, serveProviderId);
        AgencyCertificationAudit agencyCertificationAudit = agencyCertificationAuditMapper.selectOne(wcaQueryWrapper);
        //使用map存贮驳回原因
        Map<String, String> rejectReasonMap = new HashMap<>();
        rejectReasonMap.put("rejectReason", agencyCertificationAudit.getRejectReason());
        return rejectReasonMap;
    }

    @Override
    public PageResult<AgencyCertificationAuditResDTO> pageQuery(AgencyCertificationAuditPageQueryReqDTO agencyCertificationAuditPageQueryReqDTO) {
        //使用mybatis plus分页查询
        Page<AgencyCertificationAudit> page = PageUtils.parsePageQuery(agencyCertificationAuditPageQueryReqDTO, AgencyCertificationAudit.class);
        Page<AgencyCertificationAudit> selectPage = agencyCertificationAuditMapper.selectPage(page, new QueryWrapper<>());

        PageResult<AgencyCertificationAuditResDTO> agencyCertificationAuditPage = PageUtils.toPage(selectPage, AgencyCertificationAuditResDTO.class);
        return agencyCertificationAuditPage;
    }

    @Override
    public void agencyCertificationAudit(Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        //获取当前审核人员id
        Long auditorId = UserContext.currentUserId();
        CurrentUser currentUser = UserContext.getCurrentUser();
        //查询当前服务人员认证信息
        LambdaQueryWrapper<AgencyCertificationAudit> acaQueryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                .eq(AgencyCertificationAudit::getAuditStatus, 0)
                .eq(AgencyCertificationAudit::getId, id);
        AgencyCertificationAudit agencyCertificationAudit = agencyCertificationAuditMapper.selectOne(acaQueryWrapper);
        agencyCertificationAudit.setAuditorId(auditorId);
        agencyCertificationAudit.setAuditorName(currentUser.getName());
        agencyCertificationAudit.setAuditTime(LocalDateTime.now());
        agencyCertificationAudit.setAuditStatus(1);
        if (ObjectUtil.isNotEmpty(certificationAuditReqDTO.getCertificationStatus())) {
            agencyCertificationAudit.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());
        } else {
            throw new BadRequestException("无认证状态");
        }
        if (StrUtil.isNotBlank(certificationAuditReqDTO.getRejectReason())) {
            agencyCertificationAudit.setRejectReason(certificationAuditReqDTO.getRejectReason());
        }
        //todo
        AgencyCertification agencyCertification = agencyCertificationMapper.selectById(agencyCertificationAudit.getServeProviderId());
        agencyCertification.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());
        agencyCertificationMapper.updateById(agencyCertification);

        agencyCertificationAuditMapper.updateById(agencyCertificationAudit);

    }


}
